﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetHackLib.Interfaces;
using NetHackLib.Weapons;
using System.Threading;

namespace NetHackLib
{
    public class Character : Movement
    {
        #region Character Fields

        string Visual = "☺";
        string name;
        Class classType;
        Race race;
        Special special;
        
        int level;
        public Position MyPos;
        //public Position currentPosition;
        double experience;
        double reqExpToLevel = 100;

        double intelligence;
        double strength;
        double dexterity;
        double agility;

        // Str
        double maxHealth;
        // Int
        double maxMana;
        // Dex
        double attackSpeed;

        // TESTING PURPOSES... SET THE CURRENT HEALTH BACK !!!

        double currentHealth = 110;
        double currentMana;
        Random value = new Random();
        Random PosX;
        Random PosY;

        List<IItem> inventory;
        IWeapon equWeapon;
        IArmor equArmor;

        public string Image
        {
            get { return Visual; }
            protected set { Visual = value; }
        }

        #endregion

        double baseDefence;
        double baseAvoid;
        double baseMinDamage;
        double baseMaxDamage;
        double Stamina;
        double movementSpeed;
        double carryCapacity;
        int currentSkillPoints;
        bool hasPoisonAtt;

        public Character(string name, Race race, Class classType, Special special)
        {
            MyPos.X1 = 2;
            MyPos.Y1 = 2;
            //The First 3 Are assigned Once the Program Starts
            //The Level Starts by Defualt at 1
            this.name = name;
            this.race = race;
            this.classType = classType;
            this.special = special;
            
            //Base Starting Level
            this.level = 1;

            //Base Stats for Any Hero
            this.strength = 4;
            this.intelligence = 4;
            this.dexterity = 4;
            this.maxHealth = 100;
            this.maxMana = 100;
            this.agility = 1;
            this.attackSpeed = 1;
            this.baseDefence = 1;
            this.Stamina = 1;
            this.movementSpeed = 1;
            this.carryCapacity = 20;
            this.hasPoisonAtt = false;
            //Will Use a Randomiser Here for avoiding an Attack
            this.baseAvoid = 1;
            this.baseMinDamage = 1;
            this.baseMaxDamage = 4;
            this.experience = 0;
            this.reqExpToLevel = 120;

            //Base Skill Points Start at 0;
            this.currentSkillPoints = 0;


            //Gets the Visual Presentation of the Character as An Image
        

            //The Hero Race Determines where the Hero Will Gain its Power and its Downfalls
            switch (this.race)
            {
                case Race.Dwarf:
                    this.strength += 3;
                    this.intelligence += 1;
                    this.dexterity += 1;
                    break;
                case Race.Human:
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 3;
                    break;
                case Race.Elf:
                    this.strength += 1;
                    this.intelligence += 3;
                    this.dexterity += 1;
                    break;
                case Race.Argonian:
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 1;
                    this.baseDefence += 2;
                    this.agility += 2;
                    break;
                case Race.Angel:
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 1;
                    this.baseAvoid += 2;
                    break;
                case Race.Demon:
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 1;
                    this.attackSpeed += 2;
                    break;
                case Race.Orc:
                    this.strength += 3;
                    this.intelligence += 0;
                    this.dexterity += 2;
                    this.maxHealth += 30;
                    break;
                case Race.Insectoid:
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 3;
                    this.baseDefence += 1;
                    this.baseAvoid += 1;
                    break;
                case Race.Undead:
                    //Weaker but Has More Benefitial Traits
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 1;
                    this.baseDefence += 1;
                    this.baseAvoid += 1;
                    this.attackSpeed += 1;
                    break;

                default:
                    break;
            }

            switch (this.classType)
            {
                case Class.Fighter:
                    //Can be Of Both Bow Or Sword Specialist
                    //Durable Close Range Player
                    this.strength += 3;
                    this.intelligence += 1;
                    this.dexterity += 1;
                    this.attackSpeed += 1;
                    this.maxHealth += 20;
                    this.maxMana += 20;
                    this.baseDefence += 2;
                    this.Stamina += 1;
                    break;
                case Class.Cleric:
                    //Generalised Player
                    this.strength += 2;
                    this.dexterity += 2;
                    this.intelligence += 2;
                    this.baseDefence += 1;
                    this.baseAvoid += 1;
                    this.attackSpeed += 1;
                    break;
                case Class.Rogue:
                    //Fast Flexible Player
                    this.strength += 1; 
                    this.intelligence += 1;
                    this.dexterity += 3;
                    this.attackSpeed += 3;
                    this.baseAvoid += 3;
                    this.movementSpeed  = 2;
                    this.agility += 1;
                    break;
                case Class.Wizzard:
                    //Mana Beasts... Advances Faster In Skilled Magics 
                    this.strength += 1;
                    this.intelligence += 3;
                    this.dexterity += 1;
                    this.maxMana += 40;
                    this.baseAvoid += 1;
                    this.currentSkillPoints += 2;
                    this.Stamina += 2;
                    break;
                case Class.BugLord:
                    //Poisons to Be Feared with Strong Outer Shells for Protection
                    this.strength += 1;
                    this.dexterity += 2;
                    this.intelligence += 1;
                    this.baseMaxDamage += 2;
                    this.baseMinDamage += 2;
                    this.baseDefence += 2;
                    

                    break;
                case Class.Dementor:
                    //Great Close Range Fighter Class
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 3;
                    this.attackSpeed += 2;
                    this.baseDefence += 1;
                    this.maxHealth += 15;
                    this.baseMinDamage += 1;
                    break;
                case Class.AntiMage:
                    //Greater Defence Against Melee...
                    //Stronger Against Magical Opponents
                    this.strength += 2;
                    this.intelligence += 2;
                    this.dexterity += 1;
                    this.maxMana += 30;
                    this.baseMaxDamage += 2;
                    this.baseAvoid += 1;
                    this.baseDefence += 1;
                    break;
                case Class.Thief:
                    //Dangerous Close Range Opponent
                    this.strength += 2;
                    this.dexterity += 2;
                    this.intelligence += 2;
                    this.attackSpeed += 3;
                    this.baseMinDamage += 2;
                    this.movementSpeed = 2;
                    this.agility += 1;
                    break;
                case Class.Warrior:
                    //Lower Startup yet a very Durable Close Range Fighter...
                    this.strength += 2;
                    this.intelligence += 1;
                    this.dexterity += 1;
                    this.maxHealth += 30;
                    this.baseDefence += 1;
                    this.baseAvoid += 1;
                    this.attackSpeed += 1;
                    this.Stamina += 1;
                    break;
                case Class.Seeker:
                    //Seekers Are Low Stats Critical Hitters SEEKING the Vulnerable Fital Areas
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 2;
                    this.baseMaxDamage += 3;
                    this.baseMinDamage += 3;
                    this.baseAvoid += 1;
                    this.Stamina += 1;
                    this.movementSpeed = 3;
                    this.agility += 1;
                    
                    break;
                default:
                    break;
            }

            switch (this.special)
            {
                case Special.Quantity:
                    this.carryCapacity += 2;
                    break;
                case Special.Damage:
                    this.baseMaxDamage += 1.5;
                    break;
                case Special.Magic:
                    this.intelligence += 1.5;
                    break;
                case Special.Flexibility:
                    this.dexterity += 1.5;
                    this.attackSpeed += 1.5;
                    this.agility += 1;
                    break;
                case Special.StatsBonus:
                    this.strength += 0.5;
                    this.intelligence += 0.5;
                    this.dexterity += 0.5;
                    break;
                case Special.PoisonAttacks:
                    this.hasPoisonAtt = true;
                    this.baseMinDamage += 1;
                    break;
                default:
                    break;
            }
        }

        bool EquipWeapon(IWeapon weapon)
        {
            if (equWeapon != null) inventory.Add(equWeapon);

            equWeapon = weapon;
            inventory.Remove(weapon);

            return true;
        }

        bool EquipArmor(IArmor armor)
        {
            if (equWeapon != null) inventory.Add(equArmor);

            equArmor = armor;
            inventory.Remove(armor);

            return true;
        }

        //public void GetCurrentWeapon()
        //{
        //    if (EquipWeapon(true))
        //    {
                
        //    }
        //}

        public void LevelUp()
        {
            Console.WriteLine("Congratulations Your Level Increased !!!");
            this.level += 1;
            

            switch (this.race)
            {
                //Influence Some Alternate Stats to Influence Race GamePlay
                //EXAMPLE OF LEVELING UP
                case Race.Dwarf:
                    this.maxHealth += 10;
                    this.maxMana += 10;
                    break;
                case Race.Human:
                    break;
                case Race.Elf:
                    break;
                case Race.Argonian:
                    break;
                case Race.Angel:
                    break;
                case Race.Demon:
                    break;
                case Race.Insectoid:
                    break;
                case Race.Orc:
                    break;
                case Race.Undead:
                    break;
                default:
                    break;
            }
            switch (this.classType)
            {
                //Influence Some Alternate Stats to Influence Class GamePlay
                case Class.Fighter:
                    //EXAMPLE OF LEVELING UP
                    this.strength += 1;
                    this.intelligence += 1;
                    this.dexterity += 1;
                    this.currentSkillPoints += 2;
                    break;
                case Class.Cleric:
                    break;
                case Class.Rogue:
                    break;
                case Class.Wizzard:
                    break;
                case Class.BugLord:
                    break;
                case Class.Dementor:
                    break;
                case Class.AntiMage:
                    break;
                case Class.Thief:
                    break;
                case Class.Warrior:
                    break;
                case Class.Seeker:
                    break;
                default:
                    break;
            }
        }

        public double GetHealth()
        {
            double myHealth;
            myHealth = this.currentHealth;
            return myHealth;
        }

        public void BasicCharInfo()
        {
            Console.WriteLine("Name : {0} \n Race : {1} \n Class : {2}",this.name, this.race, this.classType);
        }

        //Display the Character information
        public override string ToString()
        {
            return string.Format("Name: {0}\nRace: {1}\nClass: {2}\n \n Stats : \n str: {3}\n dex: {4}\n int: {5}\n Health: {6}\n Mana: {7}\n Avoid: {8}\n Defence: {9}\n Att Speed: {10}\n Min Damage: {11}\n Max Damage: {12}\n Move Speed: {13}\n Special: {14}",
                this.name, this.race, this.classType, this.strength, this.dexterity, this.intelligence, this.maxHealth, this.maxMana, this.baseAvoid, this.baseDefence, this.attackSpeed, this.baseMinDamage, this.baseMaxDamage, this.movementSpeed, this.special);
        }

        public void generateMap()
        {
            for (int i = 0; i < 20; i++)
            {

                for (int x = 0; x < 20; x++)
                {
                    Console.Write("*");
                }

                Console.WriteLine("*");
            }
        }

        //just randoms 2 values for X and y positions on map
        public void GeneratePosXY()
        {
            //  Console.WriteLine("Input X position on map");
            for (int i = 0; i < 100; i++)
            {


                this.PosX = new Random(value.Next(1, 100));
            }
            //   Console.WriteLine("Input Y Position on Map");
            for (int i = 0; i < 100; i++)
            {
                this.PosY = new Random();
            }

        }

        //generates health acording to class chosen and lever of character
        public void GenerateHealth()
        {
            this.maxHealth = (((this.agility) / 3 + (this.dexterity) / 3 + (this.intelligence) / 3 + (this.strength)) * 3) / 2;
        }
        //generates Mana acording to class chosen and lever of character
        public void GenerateMana()
        {
            this.maxMana = (((this.agility) / 3 + (this.dexterity) / 3 + (this.intelligence) + (this.strength) / 3) * 3) / 2;
        }
        public void LevelStatsIncrease()
        {
            this.maxHealth += 10;
            this.maxMana += 10;
            this.agility += 1;
            this.currentSkillPoints += 10;
            this.intelligence += 1;
            this.movementSpeed += 1;
            this.Stamina += 1;
            this.strength += 1;

            //Gradualy Increase The REQUIRED levelling Experience
            this.reqExpToLevel = reqExpToLevel * 1.5;
            
        }

        public void InflictPoison()
        {
            for (int i = 0; i < maxMana / 100 * 1.14  ; i++)
            {
                //Inflict Damage on Enemy
            }
        }

        public void ReceivePoison()
        {
            //Make this according to enemy Level Or Strength
            for (int i = 0; i < 3; i++)
            {
                this.currentHealth = currentHealth - 3;

                //Beep Indicates Poisoned Character... With a 2 Second Delay on Damages
                Console.Beep();
                Thread.Sleep(2000);
            }
        }

        public void Burden()
        {
            this.carryCapacity = this.carryCapacity -= 2;
        }

        public void DecreaseArmor()
        {
            this.baseDefence = this.baseDefence = -1;
        }

        public void DecreaseAttSpeed()
        {
            this.attackSpeed = this.attackSpeed - 1;
        }

        public void ApplySpecial()
        {
            for (int i = 0; i < 5; i++)
            {
                switch (this.special)
                {
                    case Special.Quantity:
                        break;
                    case Special.Damage:
                        break;
                    case Special.Magic:
                        break;
                    case Special.Flexibility:
                        break;
                    case Special.StatsBonus:
                        break;
                    case Special.PoisonAttacks:
                        break;
                    default:
                        break;
                }   
            }
        }
    }
}
